package com.raceway.ihcenterapp.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.raceway.ihcenterapp.domain.IHS;
import com.raceway.ihcenterapp.domain.Audio;
import com.raceway.ihcenterapp.domain.CenterAppConstants;
import com.raceway.ihcenterapp.domain.GPS;
import com.raceway.ihcenterapp.domain.HelpRequest;
import com.raceway.ihcenterapp.domain.PhoneInfo;
import com.raceway.ihcenterapp.domain.Picture;
import com.raceway.ihcenterapp.domain.Video;
import com.sun.xml.internal.messaging.saaj.packaging.mime.util.QEncoderStream;

@RequestMapping("/androidhelprequest/**")
@Controller
public class AndroidHelpRequest {
	@PersistenceContext
	private EntityManager em;
	@ResponseBody
	@RequestMapping(value = "/ajax", method = RequestMethod.POST)
	public Object ajaxLogin(HttpServletRequest request) {
		String email = request.getParameter("userName");
		Map<String, Object> map = new HashMap<String, Object>();
		try {

			map.put("status", "true");
			map.put("email", email);
		} catch (Exception e) {
			map.put("status", false);
		}
		return map;
	}

	// created new request from android phone
	@ResponseBody
	@RequestMapping(value = "/newHelpRequest",method=RequestMethod.POST)
	public Object newHelpRequest(HttpServletRequest httpRequest) {
		String userNick = httpRequest.getParameter("userNick");
		String userPassword = httpRequest.getParameter("userPassword");
		String phoneId = httpRequest.getParameter("phoneId");
		HelpRequest helpRequest = new HelpRequest();
		try {
			helpRequest = HelpRequest.class.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		helpRequest.setIsIntervened(false);
		helpRequest.setPhoneId(phoneId);
		java.util.Date date = new java.util.Date();
		helpRequest.setHelpRequestDate(date);
		Map<String, Object> data = new HashMap<String, Object>();
		TypedQuery<PhoneInfo> phoneInfoes = PhoneInfo
				.findPhoneInfoesByAndroidId(phoneId);
		EntityManager em = PhoneInfo.entityManager();
		Query q = em
				.createQuery(
						"SELECT PhoneInfo FROM PhoneInfo AS phoneinfo WHERE phoneinfo.androidId = :androidId and phoneinfo.userPassword= :userpassword and phoneinfo.userNick= :usernick",
						PhoneInfo.class);
		q.setParameter("androidId", phoneId);
		q.setParameter("userpassword", userPassword);
		q.setParameter("usernick", userNick);
		PhoneInfo phoneInfo=(PhoneInfo) q.getSingleResult();
		helpRequest.setPhoneInfo(phoneInfo);
		if (phoneInfo==null){
			data.put("requestid", "-1");
		}else{
			helpRequest.setPhoneId(phoneId);
			helpRequest.persist();
			data.put("requestId",helpRequest.getId().toString());
		}
		
		
		return data;

	}

	// create phoneinfo object that request from android phone
	@ResponseBody
	@RequestMapping(value = "/newPhoneInfo", method = RequestMethod.POST)
	public Object newPhoneInfo(HttpServletRequest httpRequest) {
		PhoneInfo phoneInfo = new PhoneInfo();
		String userNick = httpRequest.getParameter("userNick");
		String userPassword = httpRequest.getParameter("userPassword");
		phoneInfo.setAndroidId(httpRequest.getParameter("androidId"));
		phoneInfo.setUserAddress(httpRequest.getParameter("userAddress"));
		phoneInfo.setSurname(httpRequest.getParameter("userSurname"));
		phoneInfo.setTCNO(httpRequest.getParameter("userTCNo"));
		phoneInfo.setUserEmail(httpRequest.getParameter("userEmail"));
		phoneInfo.setUsername(httpRequest.getParameter("userName"));
		phoneInfo.setUserPhone(httpRequest.getParameter("userTel"));
		phoneInfo.setUserIMEI(httpRequest.getParameter("IMEI"));
		phoneInfo.setUserNick(httpRequest.getParameter("userNick"));
		phoneInfo.setUserPassword(httpRequest.getParameter("userPassword"));
		EntityManager em = PhoneInfo.entityManager();
		Query query = em.createQuery("SELECT PhoneInfo FROM PhoneInfo AS phoneinfo WHERE phoneinfo.userPassword= :userpassword and phoneinfo.userNick= :usernick");
		query.setParameter("usernick", userNick);
		query.setParameter("userpassword", userPassword);
		List<PhoneInfo> phoneInfoList =  query.getResultList();
		Map<String, Object> data = new HashMap<String, Object>();
		if (phoneInfoList.size()==0){
			phoneInfo.persist();
			data.put("result", "successfull");
		}else{
			data.put("result", "already exist username and password. Choose different one!");
		}
		
		
		return data;
	}

	// for phone info update when Android phone update
	@ResponseBody
	@RequestMapping(value = "/updatePhoneInfo",method=RequestMethod.POST)
	public  Object updatePhoneInfo(HttpServletRequest httpRequest) {
		String androidId = httpRequest.getParameter("androidId");
		String oldUserPassword = httpRequest.getParameter("oldUserPassword");
		String oldUserNick = httpRequest.getParameter("oldUserNick");
		Map<String, Object> data = new HashMap<String, Object>();
		TypedQuery<PhoneInfo> phoneInfoes = PhoneInfo
				.findPhoneInfoesByAndroidId(androidId);
		EntityManager em = PhoneInfo.entityManager();
		Query q = em
				.createQuery(
						"SELECT PhoneInfo FROM PhoneInfo AS phoneinfo WHERE phoneinfo.androidId = :androidId and phoneinfo.userPassword= :userpassword and phoneinfo.userNick= :usernick",
						PhoneInfo.class);
		q.setParameter("androidId", androidId);
		q.setParameter("userpassword", oldUserPassword);
		q.setParameter("usernick", oldUserNick);
		PhoneInfo phoneInfo = (PhoneInfo) q.getSingleResult();
		int phoneInfoId = phoneInfoes.getFirstResult();
		phoneInfo.setAndroidId(httpRequest.getParameter("androidId"));
		phoneInfo.setUserAddress(httpRequest.getParameter("userAddress"));
		phoneInfo.setSurname(httpRequest.getParameter("userSurname"));
		phoneInfo.setTCNO(httpRequest.getParameter("userTCNo"));
		phoneInfo.setUserEmail(httpRequest.getParameter("userEmail"));
		phoneInfo.setUsername(httpRequest.getParameter("userName"));
		phoneInfo.setUserPhone(httpRequest.getParameter("userTel"));
		phoneInfo.setUserIMEI(httpRequest.getParameter("IMEI"));
		phoneInfo.setUserNick(httpRequest.getParameter("userNick"));
		phoneInfo.setUserPassword(httpRequest.getParameter("userPassword"));
		phoneInfo.persist();
		data.put("result", "successfull");
		return data;
	}

	// Create GPS data for help request when android app send HttpREquest Data
	@ResponseBody
	@RequestMapping(value = "/newGPSData",method=RequestMethod.POST)
	public Object newGPSData(HttpServletRequest httpRequest) {
		String androidId = httpRequest.getParameter("androidId");
		String requestId = httpRequest.getParameter("requestId");
		String GPSX = httpRequest.getParameter("gpsx");
		String GPSY = httpRequest.getParameter("gpsy");
		HelpRequest helpRequest=HelpRequest.findHelpRequest(Long.parseLong(requestId));      
        Query query=em.createQuery("SELECT GPS FROM GPS AS gps WHERE gps.HelpRequestId = :HelpRequestId");
        query.setParameter("HelpRequestId", helpRequest);
        List<GPS> GPSList =  query.getResultList();
        List<IHS>ASIList=IHS.findAllIHSS();
        int index = -1;
		if (GPSList.size()==0){
			index=findNearestHelpStation(GPSX,GPSY,ASIList);
		}
        
		GPS gps = new GPS();
		gps.setHelpRequestId(helpRequest);
		gps.setLatitude(Double.parseDouble(GPSX));
		gps.setLongtitude(Double.parseDouble(GPSY));
		java.util.Date date = new java.util.Date();
		gps.setGPSDate(date);
		if(index!=-1){
			
			String asiIndex=ASIList.get(index).getId().toString();
			Integer asiIndex1=Integer.parseInt(asiIndex);
			if(helpRequest.getAssignedASI1()==null){
				
				helpRequest.setAssignedASI1(ASIList.get(index));
				helpRequest.persist();
			}
			
		}

		gps.persist();
		Map<String, Object> data=new HashMap<String, Object>();
		data.put("result","successfull");
		return data;
	}

	private int findNearestHelpStation(String lat11, String lon11, List<IHS> aSIList) {
		//Haversşan Formula
		double R = 6371; // km
		double mindistance = 0;
		int index = -1;
		for (int i = 0; i < aSIList.size(); i++) {
			double dLat;
			double dLon;
			double lat1=Double.parseDouble(lat11)*Math.PI/180;
			double lat2;
			lat2=aSIList.get(i).getLatitude()*Math.PI*180;
			dLat=(aSIList.get(i).getLatitude()-Double.parseDouble(lat11))*Math.PI/180;
			dLon=(aSIList.get(i).getLongtitude()-Double.parseDouble(lon11))*Math.PI/180;		
			double a=Math.sin(dLat/2) * Math.sin(dLat/2) +Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
			double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
			double distance=R*c;
			if(i==0){
				mindistance=distance;
				index=i;
			}
			if(distance<mindistance){
				mindistance=distance;
				index=i;
			}
				
		}
		return index;

//		var R = 6371; // km
//		var dLat = (lat2-lat1).toRad();
//		var dLon = (lon2-lon1).toRad();
//		var lat1 = lat1.toRad();
//		var lat2 = lat2.toRad();
//
//		var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
//		        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
//		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
//		var d = R * c;
		
	}

	// Create audio data for help request when android app send HttpREquest Data
	@ResponseBody
	@RequestMapping(value = "/newAudio",method=RequestMethod.POST)
	public Object newAudio(HttpServletRequest httpRequest) {
		String androidId = httpRequest.getParameter("androidId");
		String requestId = httpRequest.getParameter("requestId");
		String audioPath = httpRequest.getParameter("audioPath");
		audioPath=CenterAppConstants.DEFAULT_AUDIO_PATH+audioPath;
		HelpRequest helpRequest=HelpRequest.findHelpRequest(Long.parseLong(requestId));
		Audio audio = new Audio();
		audio.setHelpRequestId(helpRequest);
		audio.setAudioPath(audioPath);
		java.util.Date date = new java.util.Date();
		audio.setAudioDate(date);
		audio.persist();
		Map<String, Object> data=new HashMap<String, Object>();
		data.put("result","successfull");
		return data;
	}

	// Create audio data for help request when android app send HttpREquest Data
	@ResponseBody
	@RequestMapping(value = "/newPicture",method=RequestMethod.POST)
	public Object newPicture(HttpServletRequest httpRequest) {
		String androidId = httpRequest.getParameter("androidId");
		String picturePath = httpRequest.getParameter("picturePath");
		picturePath=CenterAppConstants.DEFAULT_PICTURE_PATH+picturePath;
		String helpRequestid = httpRequest.getParameter("requestId");
		HelpRequest helpRequest=HelpRequest.findHelpRequest(Long.parseLong(helpRequestid));
		Picture picture = new Picture();
		picture.setHelpRequestId(helpRequest);
		picture.setPicturePath(picturePath);
		java.util.Date date = new java.util.Date();
		picture.setPictureDate(date);
		picture.persist();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("result", "successfull");
		return data;
	}
	
	// Create video data for help request when android app send HttpREquest Data
	@ResponseBody
	@RequestMapping(value = "/newVideo",method=RequestMethod.POST)
	public Object newVideo(HttpServletRequest httpRequest) {
		String androidId = httpRequest.getParameter("androidId");
		String videoPath = httpRequest.getParameter("videoPath");
		videoPath=CenterAppConstants.DEFAULT_VIDEO_PATH+videoPath;
		String helpRequestid = httpRequest.getParameter("requestId");
		HelpRequest helpRequest=HelpRequest.findHelpRequest(Long.parseLong(helpRequestid));
		Video video=new Video();
		video.setHelpRequestId(helpRequest);
		video.setVideoPath(videoPath);
		java.util.Date date = new java.util.Date();
		video.setVideoDate(date);
		video.persist();
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("result", "successfull");
		return data;
	}

	@ResponseBody
	@RequestMapping(value = "/test")
	public ResponseEntity<Map<String, Object>> test1(
			HttpServletRequest httpRequest) {
		Map<String, Object> responseBody = new HashMap<String, Object>();
		responseBody.put("ids", "deneme");
		return new ResponseEntity<Map<String, Object>>(responseBody,
				HttpStatus.OK);
	}

	@RequestMapping(value = "/deneme")
	public @ResponseBody
	String deneme(HttpServletRequest request) {
		String d;
		return "dasd";
	}

	private String getDateTime() {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		return dateFormat.format(date);
	}

}